//
//  GMDataController.m
//  GradientColorNav
//
//  Created by steven on 2016/12/9.
//  Copyright © 2016年 steven. All rights reserved.
//

#import "GMDataController.h"
#import "GMReachability.h"

@interface GMDataController ()

@end

@implementation GMDataController

- (id)init {
    self = [super init];
    if (self) {
        self.manager = [AFHTTPSessionManager manager];
        self.manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    }

    return self;
}

#pragma mark - request

- (void)requestWithType:(TYPE)type url:(NSString *)url params:(NSDictionary *)params success:(GMSuccessCallback)success failure:(GMFailureCallback)failure {
    // set token first
    [self setToken];

    switch (type) {
        case GET: {
            [self.manager GET:[PATH_API stringByAppendingString:url] parameters:params progress:nil
                      success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
                          success(responseObject);
                      } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                        NSString *errorMessage = nil;
                        NSDictionary *errorDict;

                        NSData *responseErrorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
                        if (responseErrorData) {
                            errorDict = [NSJSONSerialization JSONObjectWithData:responseErrorData options:0 error:nil];
                        }

                        if ([errorDict.allKeys containsObject:@"message"]) {
                            errorMessage = errorDict[@"message"];
                        }

                        NSHTTPURLResponse *httpResponse = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.response"];
                        if (httpResponse) {
                            failure(httpResponse.statusCode, errorMessage);
                        } else {
                            // check user network
                            // Allocate a reachability object
                            GMReachability *reach = [GMReachability reachabilityWithHostname:@"www.baidu.com"];

                            // Set the blocks
                            reach.reachableBlock = ^(GMReachability *reach) {
                                [reach stopNotifier];
                                failure(SERVER_NETWORK_OFF, nil);
                            };

                            reach.unreachableBlock = ^(GMReachability *reach) {
                                [reach stopNotifier];
                                failure(USER_NETWORK_OFF, nil);
                            };

                            // Start the notifier, which will cause the reachability object to retain itself!
                            [reach startNotifier];
                        }
                    }];
            break;
        }
        case POST: {
            [self.manager POST:[PATH_API stringByAppendingString:url] parameters:params progress:nil
                       success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
                           success(responseObject);
                       } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                        NSString *errorMessage = nil;
                        NSDictionary *errorDict;

                        NSData *responseErrorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
                        if (responseErrorData) {
                            errorDict = [NSJSONSerialization JSONObjectWithData:responseErrorData options:0 error:nil];
                        }

                        if ([errorDict.allKeys containsObject:@"message"]) {
                            errorMessage = errorDict[@"message"];
                        }

                        NSHTTPURLResponse *httpResponse = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.response"];
                        if (httpResponse) {
                            failure(httpResponse.statusCode, errorMessage);
                        } else {
                            // check user network
                            // Allocate a reachability object
                            GMReachability *reach = [GMReachability reachabilityWithHostname:@"www.baidu.com"];

                            // Set the blocks
                            reach.reachableBlock = ^(GMReachability *reach) {
                                [reach stopNotifier];
                                failure(SERVER_NETWORK_OFF, errorMessage);
                            };

                            reach.unreachableBlock = ^(GMReachability *reach) {
                                [reach stopNotifier];
                                failure(USER_NETWORK_OFF, errorMessage);
                            };

                            // Start the notifier, which will cause the reachability object to retain itself!
                            [reach startNotifier];
                        }
                    }];
            break;
        }
        case PUT: {
            break;
        }
        case DELETE: {
            break;
        }

        default:
            break;
    }
}

#pragma mark - post with data

- (void)postWithurl:(NSString *)url params:(NSDictionary *)params formData:(GMFormDataCallback)formData success:(GMSuccessCallback)success failure:(GMFailureCallback)failure {
    // set token first
    [self setToken];

    [self.manager POST:[PATH_API stringByAppendingString:url] parameters:params constructingBodyWithBlock:formData progress:nil
               success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) {
                   success(responseObject);
               } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) {
                NSString *errorMessage = nil;
                NSDictionary *errorDict;

                NSData *responseErrorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
                if (responseErrorData) {
                    errorDict = [NSJSONSerialization JSONObjectWithData:responseErrorData options:0 error:nil];
                }

                if ([errorDict.allKeys containsObject:@"message"]) {
                    errorMessage = errorDict[@"message"];
                }

                NSHTTPURLResponse *httpResponse = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.response"];
                if (httpResponse) {
                    failure(httpResponse.statusCode, errorMessage);
                } else {
                    // check user network
                    // Allocate a reachability object
                    GMReachability *reach = [GMReachability reachabilityWithHostname:@"www.baidu.com"];

                    // Set the blocks
                    reach.reachableBlock = ^(GMReachability *reach) {
                        [reach stopNotifier];
                        failure(SERVER_NETWORK_OFF, errorMessage);
                    };

                    reach.unreachableBlock = ^(GMReachability *reach) {
                        [reach stopNotifier];
                        failure(USER_NETWORK_OFF, errorMessage);
                    };

                    // Start the notifier, which will cause the reachability object to retain itself!
                    [reach startNotifier];
                }
            }];
}


#pragma mark - set token for authorization header

- (void)setToken {
    // set token for each request, incase for update password
    NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:@"token"];
    if (token) {
        [self.manager.requestSerializer setValue:[@"bearer" stringByAppendingString:token] forHTTPHeaderField:@"Authorization"];
    }
}

@end
